package com.roc.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.roc.bean.FreezeBean;
import com.roc.dao.IBaseDao;
import com.roc.dao.ISQLBaseDao;
import com.roc.newPage.IPageDao;
import com.roc.pojo.Operators;
import com.roc.service.ServiceException;
import com.roc.service.TmpStrongDeducService;
import com.roc.util.Constance;
import com.roc.util.DateUtil;
import com.roc.util.constant.SysLogType;
@Service
public class TmpStrongDeducServiceImpl implements TmpStrongDeducService{
	
	private static Logger logger = Logger.getLogger(TmpStrongDeducServiceImpl.class);
	
	@Autowired
	private IPageDao pageDao;
	
	@Autowired
	private ISQLBaseDao sqlBaseDao;
	
	@Autowired
	private IBaseDao baseDao;
	
	/**
	 * 临时强扣
	 * 1、插入强扣表数据
	 * 2、查询结算完成出款数据，按商户操作出款记录
	 */
	@Transactional(rollbackFor = { ServiceException.class })
	@Override
	public synchronized Map<String, Object> saveDeducInfo(Operators logingMerchant,
			FreezeBean freezeBean) throws ServiceException {
		String insertSql="INSERT INTO APSTFR.TBL_TFR_MCHNT_FREEZE_LIST(KEY_STR,MCHNT_CD,FREEZE_AMT,FREEZE_HAD_SUM, "
				+ "FREEZE_WEI_SUM,USE_STATUS,FREEZE_FLAG,OLD_TRANS_KEY,OLD_TRANS_CARD_NO,RESVER1,RESVER2,REC_CRT_TS) "
				+ " VALUES(?,?,?,?,?,?,?,?,?,?,?,SYSTIMESTAMP) ";
		String selSql = "select t.remark1,t.freeze_amt,t.un_freeze_amt,t.INS_ID_CD,t.BANK_CODE,t.BANK_NAME,t.ACCOUNT,t.ACCOUNT_NAME "
				+ " from t_settle_item t where t.mcht_cd=? and t.settleflag='1' and t.settledate=? ";
		String updSql = "update t_settle_item t set t.freeze_amt=?,t.un_freeze_amt=?,t.dt_update=sysdate where t.remark1=? and t.settleflag='1' and t.settledate=? ";
		String insertLogSql = "INSERT INTO APSTFR.TBL_TFR_TRN_FREEZE_LOG(KEY_STR,NOW_FREEZE_AMT "
				+ ",TRANS_DT,REC_CRT_TS,MCHNT_CD,INDUSTRY_INS_ID_CD,PYE_BANK_NO, "
				+ "PYE_BANK_NM,PYE_ACCT_NO,PYE_ACCT_NM) "
				+"VALUES(?,?,?,systimestamp,?,?,?,?,?,?) ";
		String proIndexSQL="SELECT APSTFR.TBL_TFR_FREEZE_SEQ.NEXTVAL FROM  DUAL ";//创建序列单独拿出便于记录到系统日志
		
		Map<String,Object> resMap = new HashMap<String, Object>();
		List<Object> paramsList = new ArrayList<Object>();
		/**
		 * 以下计算以分为单位来计算
		 */
		try {
			String mchtCd = Constance.Null2EmptyTrim(freezeBean.getMchntCd());//页面参数-商户号
			
			if("".equals(mchtCd)){
				resMap.put("flag", false);
				resMap.put("msg", "商户号为空");
				return resMap;
			}
			
			String fa_list = Constance.Null2EmptyTrim(freezeBean.getFreezeAmt());//页面参数-冻结金额(元)
			
			if("".equals(fa_list)){
				resMap.put("flag", false);
				resMap.put("msg", "冻结金额为空");
				return resMap;
			}
			
			if("".equals(Constance.Null2EmptyTrim(freezeBean.getRemark()))){//页面参数-备注
				resMap.put("flag", false);
				resMap.put("msg", "备注为空");
				return resMap;
			}
			
			/**
			 * 页面参数冻结金额转分
			 */
			long fa_page = new BigDecimal(fa_list).multiply(new BigDecimal(100)).longValue(); 
			
			if(fa_page <= 0){
				resMap.put("flag", false);
				resMap.put("msg", "冻结金额必须大于0");
				return resMap;
			}
			
			
			String settleDate = DateUtil.getDate(new Date(),0,"yyyyMMdd");//出款跑批日期
			//生成强扣记录ID,便于记录流水
			Object obj=baseDao.createSQLQueryUniqueResult(proIndexSQL);
			long index = Long.parseLong(String.valueOf(obj));
			//先查询是否有出款记录
			List<Object> itemList = pageDao.querySqlAll(selSql, new Object[]{mchtCd,settleDate});
			long fa_var = 0;//临时变量-本次已冻结金额累计,单位(分)
			if(itemList != null && itemList.size()>0){
				Iterator it = itemList.iterator();
				while(it.hasNext()){
					long fa_now = 0;//对应本笔出款记录冻结的金额,单位(分)
					Object[] objs = (Object[]) it.next();
					String remark1 = Constance.Null2EmptyTrim(objs[0]);
					String freezeAmt = Constance.Null2EmptyTrim(objs[1]);//出款表已冻结金额(元)
					String unFreezeAmt = Constance.Null2EmptyTrim(objs[2]);//出款表出款金额(元)
					String insIdCd = Constance.Null2EmptyTrim(objs[3]);
					String bankCd = Constance.Null2EmptyTrim(objs[4]);
					String bankName = Constance.Null2EmptyTrim(objs[5]);
					String account = Constance.Null2EmptyTrim(objs[6]);
					String accountName = Constance.Null2EmptyTrim(objs[7]);
					
					logger.info(logingMerchant.getAccountNo()+"开始操作出款表数据，已冻结金额【"+freezeAmt+"】，出款金额【"+unFreezeAmt+"】，唯一索引【"+remark1+"】");
					
					if("".equals(unFreezeAmt)){
						resMap.put("flag", false);
						resMap.put("msg", "出款表出款金额为空");
						return resMap;
					}
					
					if("".equals(freezeAmt)){
						resMap.put("flag", false);
						resMap.put("msg", "出款表冻结金额为空");
						return resMap;
					}
					
					if("".equals(remark1)){
						resMap.put("flag", false);
						resMap.put("msg", "出款表唯一索引为空");
						return resMap;
					}
					
					/**
					 * 出款表数据元转分
					 */
					long fa_item = new BigDecimal(freezeAmt).multiply(new BigDecimal(100)).longValue();//出款表已冻结金额，单位(分)
					long ufa_item = new BigDecimal(unFreezeAmt).multiply(new BigDecimal(100)).longValue();//出款表出款金额,单位(分)
					
					
					//页面冻结金额大于出款金额，本条出款记录出款金额为0，页面冻结金额=页面冻结金额-出款金额 ,出款表冻结金额=出款表冻结金额+本次循环冻结的金额
					if(fa_page>=ufa_item){
						fa_now = ufa_item;
						fa_item = new BigDecimal(fa_item).add(new BigDecimal(ufa_item)).longValue();
						fa_var = new BigDecimal(fa_var).add(new BigDecimal(ufa_item)).longValue();
						ufa_item = 0;
					}
					
					//页面冻结金额小于出款金额
					if(fa_page<ufa_item){
						fa_now = fa_page;
						fa_item = new BigDecimal(fa_item).add(new BigDecimal(fa_page)).longValue();
						ufa_item = new BigDecimal(ufa_item).subtract(new BigDecimal(fa_page)).longValue();
						fa_var = new BigDecimal(fa_var).add(new BigDecimal(fa_page)).longValue();
					}
					
					paramsList.clear();
					paramsList.add(new BigDecimal(fa_item).divide(new BigDecimal(100)).toPlainString());
					paramsList.add(new BigDecimal(ufa_item).divide(new BigDecimal(100)).toPlainString());
					paramsList.add(remark1);
					paramsList.add(settleDate);
					//计算出款表的冻结金额和出款金额
					int updCount = sqlBaseDao.deleteBySql(updSql, paramsList);
					if(updCount != 1){
						throw new ServiceException("修改出款表数据异常");
					}
					
					//生成强扣流水
					if(fa_now > 0){
						paramsList.clear();
						paramsList.add(index);
						paramsList.add(fa_now);
						paramsList.add(settleDate);
						paramsList.add(mchtCd);
						paramsList.add(insIdCd);
						paramsList.add(bankCd);
						paramsList.add(bankName);
						paramsList.add(account);
						paramsList.add(accountName);
						int insertLogCount = sqlBaseDao.deleteBySql(insertLogSql, paramsList);
						if(insertLogCount != 1){
							throw new ServiceException(logingMerchant.getAccountNo()+"保存强扣流水异常");
						}
					}
					
					
					fa_page = new BigDecimal(fa_page).subtract(new BigDecimal(fa_now)).longValue();
					if(fa_page<=0){
						logger.info(logingMerchant.getAccountNo()+"强扣金额扣完：【"+fa_page+"】");
						break;
					}
					
				}
			}
			
			//保存强扣记录
			paramsList.clear();
			paramsList.add(index);
			paramsList.add(mchtCd);
			paramsList.add(new BigDecimal(freezeBean.getFreezeAmt()).multiply(new BigDecimal(100)).longValue());
			paramsList.add(fa_var);
			paramsList.add((new BigDecimal(freezeBean.getFreezeAmt()).multiply(new BigDecimal(100))).subtract(new BigDecimal(fa_var)).longValue());
			paramsList.add("1");
			if(new BigDecimal(freezeBean.getFreezeAmt()).multiply(new BigDecimal(100)).longValue()==fa_var){
				paramsList.add("1");
			}else if(new BigDecimal(freezeBean.getFreezeAmt()).multiply(new BigDecimal(100)).longValue()>fa_var){
				paramsList.add("0");
			}else{
				throw new ServiceException("临时强扣冻结异常：应冻结金额小于累计冻结的金额");
			}
			paramsList.add("");
			paramsList.add("");
			paramsList.add(Constance.Null2EmptyTrim(freezeBean.getRemark()));
			paramsList.add(logingMerchant.getAccountNo());
			
			int insertCount = sqlBaseDao.deleteBySql(insertSql, paramsList);
			if(insertCount != 1){
				throw new ServiceException("保存强扣记录异常");
			}
			
			baseDao.addSyslog(SysLogType.INSERT_TMP_STRONG_DEDUC.getCode(),
					SysLogType.INSERT_TMP_STRONG_DEDUC.getName(),
					logingMerchant.getAccountNo(), 
					String.valueOf(index));
			
			logger.info(logingMerchant.getAccountNo()+"临时强扣商户【"+mchtCd+"】操作完毕");
		} catch (Exception e) {
			resMap.put("flag", false);
			resMap.put("msg", "操作异常");
			logger.error("临时强扣异常："+e);
			e.printStackTrace();
			throw new ServiceException("临时强扣异常");
		}
		resMap.put("flag", true);
		resMap.put("msg", "操作成功");
		return resMap;
	}
}
